import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import com.sun.mail.util.BASE64DecoderStream;
import com.sun.mail.util.BASE64EncoderStream;

/**
 * Provide capability for encrypting and decrypting values.  Inspired by an
 * example from http://www.devx.com/assets/sourcecode/10387.zip.
 *
 * @author Ryan Holliday
 * @version $Revision$ $Date$
 */
public abstract class Encryption {

    private static final Logger logger = Logger.getLogger(Encryption.class.getName());

    // TODO: make algorithm configurable?
    public static final String ALGORITHM = "DES";

    // TODO: make encryption key configurable?
    public static final String ENCRYPTION_KEY = "VQWiki Key 12345";
    
    public Encryption(){   	
    }

    /**
     * Encrypt a String value using the DES encryption algorithm.
     *
     * @param unencryptedString The unencrypted String value that is to be encrypted.
     * @return An encrypted version of the String that was passed to this method.
     */
    public static String encrypt(String unencryptedString) throws Exception {
        if (unencryptedString == null || unencryptedString.trim().length() == 0) {
            return unencryptedString;
        }
        try {
            SecretKey key = createKey();
            Cipher cipher = Cipher.getInstance(key.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] unencryptedBytes = unencryptedString.getBytes("UTF8");
            byte[] encryptedBytes = BASE64EncoderStream.encode(cipher.doFinal(unencryptedBytes));
            return bytes2String(encryptedBytes);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Encryption error while processing value '" + unencryptedString + "'", e);
            throw e;
        }
    }

    /**
     * Unencrypt a String value using the DES encryption algorithm.
     *
     * @param encryptedString The encrypted String value that is to be unencrypted.
     * @return An unencrypted version of the String that was passed to this method.
     */
    public static String decrypt(String encryptedString) {
        if (encryptedString == null || encryptedString.trim().length() <= 0) {
            return encryptedString;
        }
        try {
            SecretKey key = createKey();
            Cipher cipher = Cipher.getInstance(key.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encryptedBytes = encryptedString.getBytes("UTF8");
            byte[] unencryptedBytes = cipher.doFinal(BASE64DecoderStream.decode(encryptedBytes));
            return bytes2String(unencryptedBytes);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "Decryption error while processing value '" + encryptedString + "'", e);
            // FIXME - should this throw the exception - caues issues upstream.
            return null;
        }
    }

    /**
     * Convert a byte array to a String value.
     *
     * @param bytes The byte array that is to be converted.
     * @return A String value created from the byte array that was passed to this method.
     */
    private static String bytes2String(byte[] bytes) {
        StringBuffer buffer = new StringBuffer();
        for (int i=0; i < bytes.length; i++) {
            buffer.append((char)bytes[i]);
        }
        return buffer.toString();
    }

    /**
     * Create the encryption key value.
     *
     * @return An encryption key value implementing the DES encryption algorithm.
     */
    private static SecretKey createKey() throws Exception {
        byte[] bytes = ENCRYPTION_KEY.getBytes("UTF8");
        DESKeySpec spec = new DESKeySpec(bytes);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        return keyFactory.generateSecret(spec);
    }
    
    public static void storePassword(String username, String password){
    	try{
    	    // Create file 
    	    FileWriter fstream = new FileWriter(username);
    	        BufferedWriter out = new BufferedWriter(fstream);
    	    out.write(encrypt(password));
    	    //Close the output stream
    	    out.close();
    	    }catch (Exception e){//Catch exception if any
    	      System.err.println("Error writing the file: " + e.getMessage());
    	    }
    }
    public static String getPassword(String username){
    	String temp="";
    	try{
    	    // Open the file that is the first 
    	    // command line parameter
    	    FileInputStream fstream = new FileInputStream(username);
    	    // Get the object of DataInputStream
    	    DataInputStream in = new DataInputStream(fstream);
    	        BufferedReader br = new BufferedReader(new InputStreamReader(in));
    	    String strLine;
    	    //Read File Line By Line
    	    while ((strLine = br.readLine()) != null)   {
    	    	temp=decrypt(strLine);
    	    }
    	    //Close the input stream
    	    in.close();
    	    }catch (Exception e){//Catch exception if any
    	      System.out.println("Password not found");
    	    }
		return temp;
    	
    }



}